home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * CagdCmpt.c - Make objects compatible. *
- *******************************************************************************
- * Written by Gershon Elber, Sep. 91. *
- ******************************************************************************/
-
- #include "cagd_loc.h"
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Given two curves, makes them compatible by: M
- * 1. Coercing their point type to be the same. M
- * 2. Making them have the same curve type. M
- * 3. Raising the degree of the lower one to be the same as the higher. M
- * 4. Refining them to a common knot vector (If Bspline and SameOrder). M
- * M
- * Note 3 is performed if SameOrder TRUE, 4 if SameKV TRUE. M
- * Both curves are modified IN PLACE. M
- * *
- * PARAMETERS: M
- * Crv1, Crv2: Two curves to be made compatible, in place. M
- * SameOrder: If TRUE, this routine make sure they share the same order. M
- * SameKV: If TRUE, this routine make sure they share the same M
- * knot vector and hence continuity. *
- * *
- * RETURN VALUE: M
- * CagdBType: TRUE if successful, FALSE otherwise. M
- * *
- * KEYWORDS: M
- * CagdMakeCrvsCompatible, compatibility M
- *****************************************************************************/
- CagdBType CagdMakeCrvsCompatible(CagdCrvStruct **Crv1,
- CagdCrvStruct **Crv2,
- CagdBType SameOrder,
- CagdBType SameKV)
- {
- int KV1Len, KV2Len, RefLen;
- CagdRType *KV1, *KV2, *RefKV;
- CagdCrvStruct *TCrv;
- CagdPointType CommonPType;
-
- if ((*Crv1 == NULL) || (*Crv2 == NULL))
- return TRUE;
-
- CommonPType = CagdMergePointType((*Crv1) -> PType, (*Crv2) -> PType);
-
- if (CAGD_IS_PERIODIC_CRV(*Crv1) != CAGD_IS_PERIODIC_CRV(*Crv2))
- return FALSE;
-
- /* Make the point types compatible. */
- if (CommonPType != (*Crv1) -> PType) {
- TCrv = CagdCoerceCrvTo(*Crv1, CommonPType);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- if (CommonPType != (*Crv2) -> PType) {
- TCrv = CagdCoerceCrvTo(*Crv2, CommonPType);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
-
- if (SameOrder) {
- /* Raise the degree of the lower one. */
- if ((*Crv1) -> Order < (*Crv2) -> Order) {
- TCrv = CagdCrvDegreeRaiseN(*Crv1, (*Crv2) -> Order);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- else if ((*Crv2) -> Order < (*Crv1) -> Order) {
- TCrv = CagdCrvDegreeRaiseN(*Crv2, (*Crv1) -> Order);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
- }
-
- /* If incompatible curve type - make it the same as well. */
- if ((*Crv1) -> GType != (*Crv2) -> GType) {
- /* If power basis - promote to bezier: */
- if ((*Crv1) -> GType == CAGD_CPOWER_TYPE) {
- TCrv = CnvrtPower2BezierCrv(*Crv1);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- if ((*Crv2) -> GType == CAGD_CPOWER_TYPE) {
- TCrv = CnvrtPower2BezierCrv(*Crv2);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
-
- /* Now both curves may be either bezier or bspline curves. */
- if ((*Crv1) -> GType != (*Crv2) -> GType) {
- /* If bezier basis - promote to bspline: */
- if ((*Crv1) -> GType == CAGD_CBEZIER_TYPE) {
- TCrv = CnvrtBezier2BsplineCrv(*Crv1);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- if ((*Crv2) -> GType == CAGD_CBEZIER_TYPE) {
- TCrv = CnvrtBezier2BsplineCrv(*Crv2);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
- }
- }
-
- if (SameKV && SameOrder) {
- /* If bspline curve - make sure knot vectors are the same. */
- if ((*Crv1) -> GType == CAGD_CBSPLINE_TYPE) {
- int Order = (*Crv1) -> Order;
-
- KV1 = (*Crv1) -> KnotVector;
- KV2 = (*Crv2) -> KnotVector;
- KV1Len = CAGD_CRV_PT_LST_LEN(*Crv1) + Order;
- KV2Len = CAGD_CRV_PT_LST_LEN(*Crv2) + Order;
-
- /* Affine map second knot vector to span same parametric domain. */
- BspKnotAffineTrans(KV2, KV2Len, KV1[Order - 1] - KV2[Order - 1],
- (KV1[KV1Len - Order] - KV1[Order - 1]) /
- (KV2[KV2Len - Order] - KV2[Order - 1]));
-
- /* Find knots in KV2 which are not in KV1 and refine Crv1 there. */
- RefKV = BspKnotSubtrTwo(&KV2[Order - 1], KV2Len - Order * 2 + 2,
- &KV1[Order - 1], KV1Len - Order * 2 + 2,
- &RefLen);
- if (RefLen > 0) {
- TCrv = CagdCrvRefineAtParams(*Crv1, FALSE, RefKV, RefLen);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- KV1 = (*Crv1) -> KnotVector;
- KV1Len = (*Crv1) -> Length + (*Crv1) -> Order;
- }
- IritFree((VoidPtr) RefKV);
-
- /* Find knots in KV1 which are not in KV2 and refine Crv2 there. */
- RefKV = BspKnotSubtrTwo(&KV1[Order - 1], KV1Len - Order * 2 + 2,
- &KV2[Order - 1], KV2Len - Order * 2 + 2,
- &RefLen);
- if (RefLen > 0) {
- TCrv = CagdCrvRefineAtParams(*Crv2, FALSE, RefKV, RefLen);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
- IritFree((VoidPtr) RefKV);
- }
- }
-
- return TRUE;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Given two surfaces, makes them compatible by: M
- * 1. Coercing their point type to be the same. M
- * 2. Making them have the same curve type. M
- * 3. Raising the degree of the lower one to be the same as the higher. M
- * 4. Refining them to a common knot vector (If Bspline and SameOrder). M
- * M
- * Note 3 is performed if SameOrder TRUE, 4 if SameKV TRUE. M
- * Both surface are modified IN PLACE. M
- * *
- * PARAMETERS: M
- * Srf1, Srf2: Two surfaces to be made compatible, in place. M
- * SameUOrder: If TRUE, this routine make sure they share the same U M
- * order. M
- * SameVOrder: If TRUE, this routine make sure they share the same V M
- * order. M
- * SameUKV: If TRUE, this routine make sure they share the same U M
- * knot vector and hence continuity. *
- * SameVKV: If TRUE, this routine make sure they share the same V M
- * knot vector and hence continuity. M
- * *
- * RETURN VALUE: M
- * CagdBType: TRUE if successful, FALSE otherwise. M
- * *
- * KEYWORDS: M
- * CagdMakeSrfsCompatible, compatibility M
- *****************************************************************************/
- CagdBType CagdMakeSrfsCompatible(CagdSrfStruct **Srf1,
- CagdSrfStruct **Srf2,
- CagdBType SameUOrder,
- CagdBType SameVOrder,
- CagdBType SameUKV,
- CagdBType SameVKV)
- {
- int i, KV1Len, KV2Len, RefLen;
- CagdRType *KV1, *KV2, *RefKV;
- CagdSrfStruct *TSrf;
- CagdPointType CommonPType;
-
- if ((*Srf1 == NULL) || (*Srf2 == NULL))
- return TRUE;
-
- if (CAGD_IS_UPERIODIC_SRF(*Srf1) != CAGD_IS_UPERIODIC_SRF(*Srf2) ||
- CAGD_IS_VPERIODIC_SRF(*Srf1) != CAGD_IS_VPERIODIC_SRF(*Srf2))
- return FALSE;
-
- CommonPType = CagdMergePointType((*Srf1) -> PType, (*Srf2) -> PType);
-
- /* Make the point types compatible. */
- if (CommonPType != (*Srf1) -> PType) {
- TSrf = CagdCoerceSrfTo(*Srf1, CommonPType);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- }
- if (CommonPType != (*Srf2) -> PType) {
- TSrf = CagdCoerceSrfTo(*Srf2, CommonPType);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
-
- if (SameUOrder) {
- /* Raise the degree of the lower one. */
- for (i = (*Srf1) -> UOrder; i < (*Srf2) -> UOrder; i++) {
- TSrf = CagdSrfDegreeRaise(*Srf1, CAGD_CONST_V_DIR);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- }
- for (i = (*Srf2) -> UOrder; i < (*Srf1) -> UOrder; i++) {
- TSrf = CagdSrfDegreeRaise(*Srf2, CAGD_CONST_V_DIR);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
- }
- if (SameVOrder) {
- for (i = (*Srf1) -> VOrder; i < (*Srf2) -> VOrder; i++) {
- TSrf = CagdSrfDegreeRaise(*Srf1, CAGD_CONST_U_DIR);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- }
- for (i = (*Srf2) -> VOrder; i < (*Srf1) -> VOrder; i++) {
- TSrf = CagdSrfDegreeRaise(*Srf2, CAGD_CONST_U_DIR);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
- }
-
- /* If incompatible surface type - make it the same as well. */
- if ((*Srf1) -> GType != (*Srf2) -> GType) {
- /* If power basis - promote to bezier: */
- if ((*Srf1) -> GType == CAGD_SPOWER_TYPE) {
- TSrf = CnvrtPower2BezierSrf(*Srf1);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- }
- if ((*Srf2) -> GType == CAGD_SPOWER_TYPE) {
- TSrf = CnvrtPower2BezierSrf(*Srf2);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
-
- /* Now both surfaces may be either bezier or bspline surfaces. */
- if ((*Srf1) -> GType != (*Srf2) -> GType) {
- /* If bezier basis - promote to bspline: */
- if ((*Srf1) -> GType == CAGD_SBEZIER_TYPE) {
- TSrf = CnvrtBezier2BsplineSrf(*Srf1);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- }
- if ((*Srf2) -> GType == CAGD_SBEZIER_TYPE) {
- TSrf = CnvrtBezier2BsplineSrf(*Srf2);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
- }
- }
-
- if ((*Srf1) -> GType == CAGD_SBSPLINE_TYPE) {
- /* If bspline surface - make sure knot vectors are the same. */
-
- if (SameUKV && SameUOrder) {
- /* Handle the U Direction. */
- int Order = (*Srf1) -> UOrder;
- KV1 = (*Srf1) -> UKnotVector;
- KV2 = (*Srf2) -> UKnotVector;
- KV1Len = CAGD_SRF_UPT_LST_LEN(*Srf1) + Order;
- KV2Len = CAGD_SRF_UPT_LST_LEN(*Srf2) + Order;
-
- /* Affine map second knot vector to span same parametric domain. */
- BspKnotAffineTrans(KV2, KV2Len, KV1[Order - 1] - KV2[Order - 1],
- (KV1[KV1Len - Order] - KV1[Order - 1]) /
- (KV2[KV2Len - Order] - KV2[Order - 1]));
-
- /* Find knots in KV2 which are not in KV1 and refine Srf1 there. */
- RefKV = BspKnotSubtrTwo(&KV2[Order - 1], KV2Len - Order * 2 + 2,
- &KV1[Order - 1], KV1Len - Order * 2 + 2,
- &RefLen);
- if (RefLen > 0) {
- TSrf = CagdSrfRefineAtParams(*Srf1, CAGD_CONST_U_DIR,
- FALSE, RefKV, RefLen);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- KV1 = (*Srf1) -> UKnotVector;
- KV1Len = (*Srf1) -> ULength + (*Srf1) -> UOrder;
- }
- IritFree((VoidPtr) RefKV);
-
- /* Find knots in KV1 which are not in KV2 and refine Srf2 there. */
- RefKV = BspKnotSubtrTwo(&KV1[Order - 1], KV1Len - Order * 2 + 2,
- &KV2[Order - 1], KV2Len - Order * 2 + 2,
- &RefLen);
- if (RefLen > 0) {
- TSrf = CagdSrfRefineAtParams(*Srf2, CAGD_CONST_U_DIR,
- FALSE, RefKV, RefLen);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
- IritFree((VoidPtr) RefKV);
- }
-
- if (SameVKV && SameVOrder) {
- /* Handle the V Direction. */
- int Order = (*Srf1) -> VOrder;
-
- KV1 = (*Srf1) -> VKnotVector;
- KV2 = (*Srf2) -> VKnotVector;
- KV1Len = CAGD_SRF_VPT_LST_LEN(*Srf1) + Order;
- KV2Len = CAGD_SRF_VPT_LST_LEN(*Srf2) + Order;
-
- /* Affine map second knot vector to span same parametric domain. */
- BspKnotAffineTrans(KV2, KV2Len, KV1[Order - 1] - KV2[Order - 1],
- (KV1[KV1Len - Order] - KV1[Order - 1]) /
- (KV2[KV2Len - Order] - KV2[Order - 1]));
-
- /* Find knots in KV2 which are not in KV1 and refine Srf1 there. */
- RefKV = BspKnotSubtrTwo(&KV2[Order - 1], KV2Len - Order * 2 + 2,
- &KV1[Order - 1], KV1Len - Order * 2 + 2,
- &RefLen);
- if (RefLen > 0) {
- TSrf = CagdSrfRefineAtParams(*Srf1, CAGD_CONST_V_DIR,
- FALSE, RefKV, RefLen);
- CagdSrfFree(*Srf1);
- *Srf1 = TSrf;
- KV1 = (*Srf1) -> VKnotVector;
- KV1Len = (*Srf1) -> VLength + (*Srf1) -> VOrder;
- }
- IritFree((VoidPtr) RefKV);
-
- /* Find knots in KV1 which are not in KV2 and refine Srf2 there. */
- RefKV = BspKnotSubtrTwo(&KV1[Order - 1], KV1Len - Order * 2 + 2,
- &KV2[Order - 1], KV2Len - Order * 2 + 2,
- &RefLen);
- if (RefLen > 0) {
- TSrf = CagdSrfRefineAtParams(*Srf2, CAGD_CONST_V_DIR,
- FALSE, RefKV, RefLen);
- CagdSrfFree(*Srf2);
- *Srf2 = TSrf;
- }
- IritFree((VoidPtr) RefKV);
- }
- }
-
- return TRUE;
- }
-
-